package com.wang.learn.cloudredis.utils;

import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.springframework.http.MediaType;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class HttpUtils {
	private static PoolingHttpClientConnectionManager cm = null;

	private static final String ENCODE = "UTF-8";
	private static final int CONNECT_TIMEOUT = 8000;
	public static final String HEADER_STRING = "Authorization";

	private static final int SOCKET_TIMEOUT = 5000 * 12 * 5;
	private static final int POOL_MAX = 4000;
	private static final int POOL_MAX_PER_ROUTE = 800;
	static {
		cm = new PoolingHttpClientConnectionManager();
		cm.setMaxTotal(POOL_MAX);
		cm.setDefaultMaxPerRoute(POOL_MAX_PER_ROUTE);
	}

	private static CloseableHttpClient getHttpClient() {
		RequestConfig globalConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.IGNORE_COOKIES).build();
		CloseableHttpClient client = HttpClients.custom().setConnectionManager(cm).setDefaultRequestConfig(globalConfig).build();
		return client;
	}

	public static String get(String url, Map<String, String> paramsMap) {
		return get(url, paramsMap, null);
	}

	public static String get(String url, Map<String, String> paramsMap, Map<String, String> headers) {
		HttpGet get = null;
		try {
			URIBuilder builder = new URIBuilder(url);
			if (paramsMap != null) {
				for (Iterator<String> it = paramsMap.keySet().iterator(); it.hasNext();) {
					String key = it.next();
					String value = paramsMap.get(key);
					builder.setParameter(key, value);
				}
			}
			get = new HttpGet(builder.build().toString());
			if (headers != null && !headers.isEmpty()) {
				for (Entry<String, String> header : headers.entrySet()) {
					get.setHeader(header.getKey(), header.getValue());
				}
			}
		} catch (URISyntaxException e1) {
			e1.printStackTrace();
		}
		try {
			RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(SOCKET_TIMEOUT).setConnectTimeout(CONNECT_TIMEOUT).build();
			get.setConfig(requestConfig);
			CloseableHttpResponse response = getHttpClient().execute(get);
			HttpEntity entity = response.getEntity();
			String str = EntityUtils.toString(entity, ENCODE);
			return str;
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
		}
		return null;
	}

	public static String postForm(String url, Map<String, String> paramsMap, Map<String, String> headers) {
		List<BasicNameValuePair> formparams = new ArrayList<BasicNameValuePair>();
		if (paramsMap != null) {
			for (Iterator<String> it = paramsMap.keySet().iterator(); it.hasNext();) {
				String key = it.next();
				String value = paramsMap.get(key);
				formparams.add(new BasicNameValuePair(key, value));
			}
		}
		try {
			HttpPost post = new HttpPost(url);
			CloseableHttpResponse response = null;
			UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams);
			RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(SOCKET_TIMEOUT).setConnectTimeout(CONNECT_TIMEOUT).build();
			entity.setContentEncoding(new BasicHeader(HTTP.CONTENT_ENCODING, ENCODE));
			post.setEntity(entity);
			post.setConfig(requestConfig);
			if (headers != null && !headers.isEmpty()) {
				for (Entry<String, String> header : headers.entrySet()) {
					post.setHeader(header.getKey(), header.getValue());
				}
			}
			response = getHttpClient().execute(post);
			HttpEntity resEntity = response.getEntity();
			String str = EntityUtils.toString(resEntity, ENCODE);
			return str;
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
		}
		return null;
	}

	public static String postJson(String postUrl, Object o, String header) throws ClientProtocolException, Exception {
		HttpPost post = new HttpPost(postUrl);
		post.setHeader(HTTP.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE);
		post.setHeader(HEADER_STRING, header);
		if (o != null) {
			StringEntity s = null;
			if (o instanceof String) {
				s = new StringEntity((String) o, ENCODE);
			}
			else {
				s = new StringEntity(JSONObject.toJSONString(o), ENCODE);
			}
			s.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
			post.setEntity(s);
		}
		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(SOCKET_TIMEOUT).setConnectTimeout(CONNECT_TIMEOUT).build();
		post.setConfig(requestConfig);
		CloseableHttpResponse response = getHttpClient().execute(post);
		HttpEntity entity = response.getEntity();

		String str = null;
		if (entity != null) {
			str = EntityUtils.toString(entity, ENCODE);
			post.abort();
		}
		return str;
	}

	public static String postJson(String postUrl, Object o) throws ClientProtocolException, Exception {
		HttpPost post = new HttpPost(postUrl);
		post.setHeader(HTTP.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE);
		if (o != null) {
			StringEntity s = null;
			if (o instanceof String) {
				s = new StringEntity((String) o, ENCODE);
			}
			else {
				s = new StringEntity(JSONObject.toJSONString(o), ENCODE);
			}
			s.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
			post.setEntity(s);
		}
		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(SOCKET_TIMEOUT).setConnectTimeout(CONNECT_TIMEOUT).build();
		post.setConfig(requestConfig);
		CloseableHttpResponse response = getHttpClient().execute(post);
		HttpEntity entity = response.getEntity();

		String str = null;
		if (entity != null) {
			str = EntityUtils.toString(entity, ENCODE);
			post.abort();
		}
		return str;
	}


	public static Integer postJson2C(String postUrl, Object o) throws ClientProtocolException, Exception {
		HttpPost post = new HttpPost(postUrl);
		post.setHeader(HTTP.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
		if (o != null) {
			StringEntity s = null;
			if (o instanceof String) {
				s = new StringEntity((String) o, ENCODE);
			}
			else {
				s = new StringEntity(JSONObject.toJSONString(o), ENCODE);
			}
			s.setContentType(MediaType.APPLICATION_JSON_VALUE);
			post.setEntity(s);
		}
		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(SOCKET_TIMEOUT).setConnectTimeout(CONNECT_TIMEOUT).build();
		post.setConfig(requestConfig);
		CloseableHttpResponse response = getHttpClient().execute(post);
		int statusCode = response.getStatusLine().getStatusCode();
		return statusCode;
	}

}
